package com.gezi.admin.security.utils.jwt;

import cn.hutool.core.date.DateUtil;
import io.jsonwebtoken.*;
import io.jsonwebtoken.security.Keys;
import io.jsonwebtoken.security.SecureDigestAlgorithm;
import lombok.extern.slf4j.Slf4j;

import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;

import java.security.SecureRandom;
import java.util.*;

/**
 * @Author 格子软件
 * @createDate 2024/2/10 09:00
 * @contact 公众号：格子软件 微信：13716343106 邮箱：1424529270@qq.com
 */
@Slf4j
public class JwtUtil {

    //秘钥
    private static final String KEY = "6ae854633d7f46f48c5c34fa62f85380";

    //签名人
    public static final String ISSUSER = "geziruanjian";

    /**
     * 得到token
     *
     * @param client 平台
     * @return
     */
    public static String createToken(String userId,String client) {
        Map<String, Object> header = new HashMap<>();
        header.put("alg", "HS256");
        header.put("typ", "JWT");
        header.put("timestamp", createTimestamp());
        header.put("noncestr", createNonceStr());
        header.put("qianmingren",ISSUSER);
        header.put("userId",userId);
        header.put("client",client);

        //指定加密算法
        SecureDigestAlgorithm<SecretKey, SecretKey> algorithm = Jwts.SIG.HS256;
        SecretKey key = createKey();
        // 下面就是在为payload添加各种标准声明和私有声明了
        String token = Jwts.builder()
                .signWith(key, algorithm)
                .claims(header)
//                .expiration(DateUtil.offsetHour(new Date(), 1))
//                .expiration(new Date(now + (long) 1000 * 60 * 60 * 24 * day)) //设置过期时间
                .compact();
        return token;
    }

    /**
     * 校验token.包含token过期
     * @return
     */
    public static Boolean checkToken(String token){
        try {
            SecretKey key = createKey();  //签名秘钥
            Jws<Claims> jws = Jwts.parser()
                    .verifyWith(key).build()
                    .parseSignedClaims(token);
            return true;
        }catch (ExpiredJwtException ex){
            ex.printStackTrace();
            log.error("签名失败-token过期");
        }catch (Exception ex){
            ex.printStackTrace();
            log.error("签名失败-其他原因");
        }
        return false;
    }

    /**
     * 获取body数据
     *
     * @param token
     * @return
     * @throws Exception
     */
    public static Claims getBodyByToken(String token) {
        SecretKey key = createKey();
        Jws<Claims> jws = Jwts.parser()
                .verifyWith(key).build()
                .parseSignedClaims(token);
        return jws.getPayload();
    }

    /**
     * 创建秘钥
     *
     * @return
     * @throws Exception
     */
    public static SecretKey createKey() {
        return Keys.hmacShaKeyFor(KEY.getBytes());
    }

    /**
     * 获取当前时间戳，单位秒
     * 对应【timeStamp】字段
     * @return
     */
    public static long createTimestamp() {
        return System.currentTimeMillis()/1000;
    }

    /**
     * 创建随机字符串
     * 对应字段：nonceStr
     *
     * @return String 随机字符串
     */
    public static String createNonceStr() {
        String SYMBOLS = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
        Random RANDOM = new SecureRandom();
        char[] nonceChars = new char[32];
        for (int index = 0; index < nonceChars.length; ++index) {
            nonceChars[index] = SYMBOLS.charAt(RANDOM.nextInt(SYMBOLS.length()));
        }
        return new String(nonceChars);
    }

    public static void main(String[] args) {
        String token = JwtUtil.createToken("1111","ADMIN");
        log.info("创建token：{}",token);
        log.info("校验token：{}",JwtUtil.checkToken(token));
        log.info("获取body：{}", JwtUtil.getBodyByToken(token));
    }
}
